Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added noexcept variants to function traits #298

Merged
merged 5 commits into from
Apr 5, 2024
Merged

Conversation

LuSo58
Copy link
Contributor

@LuSo58 LuSo58 commented Apr 4, 2024

When using function_traits with callable items that are noexcept, no specialization would match. Here is a simple reproduction case for this.

#include <iostream>
#include <functional>

#include "fplus/fplus.hpp"

template<typename F, typename T = typename fplus::utils::function_traits<F>::template arg<0>::type>
auto forward(F f) {
  return [f](auto x) {
    auto ret = f(x);
    return ret;
  };
}

class klass {
  public:
    int x;

    int normal() const {
      return x;
    }

    int noexc() const noexcept {
      return x;
    }
};

int half(int x) {
  return x / 2;
}

int half_noexc(int x) noexcept {
  return x / 2;
}

struct functor {
  int operator()(int x) {
    return x + 5;
  }
};

struct functor_noexc {
  int operator()(int x) noexcept {
    return x + 5;
  }
};

int main() {
  klass k = {42};
  std::cout << forward(std::mem_fn(&klass::normal))(k) << std::endl; // OK
  std::cout << forward(std::mem_fn(&klass::noexc))(k) << std::endl; // Will not compile
  std::cout << forward(half)(42) << std::endl; // OK
  std::cout << forward(half_noexc)(42) << std::endl; // Will not compile
  std::cout << forward(functor())(42) << std::endl; // OK
  std::cout << forward(functor_noexc())(42) << std::endl; // Will not compile
  auto lambda = [](int x) {
    return x + 10;
  };
  auto lambda_noexc = [](int x) noexcept {
    return x + 10;
  };
  std::cout << forward(lambda)(42) << std::endl; // OK
  std::cout << forward(lambda_noexc)(42) << std::endl; // Will not compile
}

EDIT

Sorry for recreating the pull request. I finally figured out the CI and also wanted to rebase the branch to tidy the commits.

This version should compile for all compilers in the CI.

@LuSo58
Copy link
Contributor Author

LuSo58 commented Apr 5, 2024

After looking into it, I found that noexcept was not initially part of the type system, but just a marker. See __cpp_noexcept_function_type at https://en.cppreference.com/w/cpp/feature_test. I changed the guard macros accordingly.

Still compiles and passes CI. See "Actions" in the fork repo.

This is probably how it's supposed to be if-ed out 😅

@Dobiasd Dobiasd merged commit 0b5d720 into Dobiasd:master Apr 5, 2024
19 checks passed
@Dobiasd
Copy link
Owner

Dobiasd commented Apr 5, 2024

The noexcept specifier is very useful in C++, so I'm delighted FunctionalPlus now supports it. 🚀

Thanks a lot for this amazing contribution (and the nice test coverage)! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants